/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
 * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
 * full text of the license. */


/**
 * @requires OpenLayers/Layer/Markers.js
 * @requires OpenLayers/Ajax.js
 */

/**
 * Class: OpenLayers.Layer.OsmRdfLayer
 * Add GeoRDF point features to your map. 
 * 
 * Inherits from:
 *  - <OpenLayers.Layer.Markers>
 *  - <OpenLayers.Layer>
 */

OsmRdfLayer = OpenLayers.Class(OpenLayers.Layer.Markers, {

    /** 
     * Property: location 
     * {String} store url of text file 
     */
    location: null,

    /** 
     * Property: features 
     * {Array(<OpenLayers.Feature>)} 
     */
    features: null,
    
    /**
     * APIProperty: formatOptions
     * {Object} Hash of options which should be passed to the format when it is
     * created. Must be passed in the constructor.
     */
    formatOptions: null, 

    /** 
     * Property: selectedFeature 
     * {<OpenLayers.Feature>} 
     */
    selectedFeature: null,

    /** 
     * APIProperty: icon 
     * {<OpenLayers.Icon>}. This determines the Icon to be used on the map
     * for this GeoRSS layer.
     */
    icon: null,

    /**
     * APIProperty: popupSize
     * {<OpenLayers.Size>} This determines the size of GeoRSS popups. If 
     * not provided, defaults to 250px by 120px. 
     */
    popupSize: null, 
    
    /** 
     * APIProperty: useFeedTitle 
     * {Boolean} Set layer.name to the first <title> element in the feed. Default is true. 
     */
    useFeedTitle: true,
    
    /**
    * Constructor: OpenLayers.Layer.GeoRSS
    * Create a GeoRSS Layer.
    *
    * Parameters:
    * name - {String} 
    * location - {String} 
    * options - {Object}
    */
    initialize: function(name, location, options) {
    	this.loaded=true;
        OpenLayers.Layer.Markers.prototype.initialize.apply(this, [name, options]);
       	this.previousLoadedBounds = map.getExtent();
       this.location = location;
        this.features = [];
        this.warningShown=false;
     },

    /**
     * Method: destroy 
     */
    destroy: function() {
        // Warning: Layer.Markers.destroy() must be called prior to calling
        // clearFeatures() here, otherwise we leak memory. Indeed, if
        // Layer.Markers.destroy() is called after clearFeatures(), it won't be
        // able to remove the marker image elements from the layer's div since
        // the markers will have been destroyed by clearFeatures().
        OpenLayers.Layer.Markers.prototype.destroy.apply(this, arguments);
        this.clearFeatures();
        this.features = null;
    },

    /**
     * Method: loadRDF
     * Start the load of the RDF data. Don't do this when we first add the layer,
     * since we may not be visible at any point, and it would therefore be a waste.
     */
    loadRDF: function(bounds) {				
    ////Ext.getCmp("progressBar").syncProgressBar();
    				//Ext.getCmp("progressBar").updateProgress(0, "requesting", false );
    	function compareBboxShift(boxA,boxB){
    	boxA=boxA.transform(googleProjection,wgs84Projection);
    		if(Math.abs(boxA.top-boxB.top) <0.002 && Math.abs(boxA.left-boxB.left)<0.002){
    			return false;
    		}
    		return true;
    	}
      
      if (this.loaded && this.visibility) {
      
      if( this.map.getZoom()>15){
      	
            var googleProjection = new OpenLayers.Projection("EPSG:900913");
        //display Projection
        var wgs84Projection = new OpenLayers.Projection("EPSG:4326");
        if(this.previousLoadedBounds==null ){
				this.previousLoadedBounds=bounds;
				this.events.triggerEvent("loadstart");
				//Ext.getCmp("progressBar").show();
				//Ext.getCmp("progressBar").updateProgress(0.2, "requesting rdf for bbox", true );
				//Ext.getCmp("progressBar").syncProgressBar();
				link="http://giv-heatmap.uni-muenster.de:8000/sparql?query=PREFIX+geo%3A+%3Chttp%3A%2F%2Fwww.w3.org%2F2003%2F01%2Fgeo%2Fwgs84_pos%23%3E%0D%0APREFIX+losm%3A+%3Chttp%3A%2F%2Fpurl.org%2Fifgi%2Flosm%23%3E%0D%0APREFIX+rdf%3A+%3Chttp%3A%2F%2Fwww.w3.org%2F1999%2F02%2F22-rdf-syntax-ns%23%3E%0D%0APREFIX+rdfs%3A+%3Chttp%3A%2F%2Fwww.w3.org%2F2000%2F01%2Frdf-schema%23%3E%0D%0A%0D%0ACONSTRUCT{%0D%0A%3Fa+rdf%3Atype+losm%3Auniversity.%0D%0A%3Fa+rdfs%3Alabel+%3Flabel.%0D%0A%3Fa+geo%3Alat+%3Flat.%0D%0A%3Fa+geo%3Along+%3Flong.%0D%0A}+%0D%0AFROM+%3Chttp%3A%2F%2Fgiv-heatmap.uni-muenster.de%3A8888%2Fresource%2Fbbox%2F";
				link+=bounds.transform(googleProjection,wgs84Projection).toBBOX();
				link+=".rdf%3E%0D%0AWHERE+{%0D%0A%3Fa+rdf%3Atype+losm%3Auniversity.%0D%0A%3Fa+rdfs%3Alabel+%3Flabel.%0D%0A%3Fa+geo%3Alat+%3Flat.%0D%0A%3Fa+geo%3Along+%3Flong.%0D%0A}&accept=text%2Fhtml";
			
				OpenLayers.Request.GET({
					url: link,
					//url: "umweg/index.php?url=http://giv-heatmap.uni-muenster.de:8888/resource/bbox/"+bounds.transform(googleProjection,wgs84Projection).toBBOX(),
					success: this.parseData,
					scope: this
				});
				this.loaded=false;
				this.previousLoadedBounds=bounds.transform(wgs84Projection,googleProjection);
		}
    		if(compareBboxShift(bounds,this.previousLoadedBounds) && !this.previousLoadedBounds.containsBounds(bounds)){
				this.events.triggerEvent("loadstart");
				//Ext.getCmp("progressBar").show();
				//Ext.getCmp("progressBar").updateProgress(0.2, "requesting rdf for bbox", true );
				//Ext.getCmp("progressBar").syncProgressBar();
				link="http://giv-heatmap.uni-muenster.de:8000/sparql?query=PREFIX+geo%3A+%3Chttp%3A%2F%2Fwww.w3.org%2F2003%2F01%2Fgeo%2Fwgs84_pos%23%3E%0D%0APREFIX+losm%3A+%3Chttp%3A%2F%2Fpurl.org%2Fifgi%2Flosm%23%3E%0D%0APREFIX+rdf%3A+%3Chttp%3A%2F%2Fwww.w3.org%2F1999%2F02%2F22-rdf-syntax-ns%23%3E%0D%0APREFIX+rdfs%3A+%3Chttp%3A%2F%2Fwww.w3.org%2F2000%2F01%2Frdf-schema%23%3E%0D%0A%0D%0ACONSTRUCT{%0D%0A%3Fa+rdf%3Atype+losm%3Auniversity.%0D%0A%3Fa+rdfs%3Alabel+%3Flabel.%0D%0A%3Fa+geo%3Alat+%3Flat.%0D%0A%3Fa+geo%3Along+%3Flong.%0D%0A}+%0D%0AFROM+%3Chttp%3A%2F%2Fgiv-heatmap.uni-muenster.de%3A8888%2Fresource%2Fbbox%2F";
				link+=bounds.toBBOX(),
				link+=".rdf%3E%0D%0AWHERE+{%0D%0A%3Fa+rdf%3Atype+losm%3Auniversity.%0D%0A%3Fa+rdfs%3Alabel+%3Flabel.%0D%0A%3Fa+geo%3Alat+%3Flat.%0D%0A%3Fa+geo%3Along+%3Flong.%0D%0A}&accept=text%2Fhtml";
			
				OpenLayers.Request.GET({
					//url: "umweg/index.php?url=http://giv-heatmap.uni-muenster.de:8888/resource/bbox/"+bounds.toBBOX(),
					url: link,
					success: this.parseData,
					scope: this
				});
				this.loaded=false;
				this.previousLoadedBounds=bounds;
				this.warningShown=false;
            }
            }else{
            	if(!this.warningShown){
        			//Ext.Msg.alert('Error', "Sorry, but RDF Data can only be loaded on a smaller zoom levels!");
        			this.warningShown=true;
        		}
        }  
        
        }
    },    
    
    /**
     * Method: moveTo
     * If layer is visible and RSS has not been loaded, load RSS. 
     * 
     * Parameters:
     * bounds - {Object} 
     * zoomChanged - {Object} 
     * minor - {Object} 
     */
    moveTo:function(bounds, zoomChanged, minor) {
        OpenLayers.Layer.Markers.prototype.moveTo.apply(this, arguments);
    //    if(this.visibility && !this.loaded){
	if(this.visibility ){
           // this.events.triggerEvent("loadstart");
           // this.events.triggerEvent("moveend");
            //this.loadRSS(bounds);
        }
    },
        
    /**
     * Method: parseData
     * Parse the data returned from the Events call.
     *
     * Parameters:
     * ajaxRequest - {<OpenLayers.Request.XMLHttpRequest>} 
     */
    parseData: function(ajaxRequest) {
     //Ext.getCmp("progressBar").syncProgressBar();
   		 //Ext.getCmp("progressBar").updateProgress(.6, "parsing data", true );
   		 //Ext.getCmp("progressBar").syncProgressBar();
				
        var doc = ajaxRequest.responseXML;
         
        if (!doc || !doc.documentElement) {
            doc = OpenLayers.Format.XML.prototype.read(ajaxRequest.responseText);
        }
        if(ajaxRequest.responseText==null && ajaxRequest.responseXML==null  ){
        				
				//Ext.getCmp("progressBar").updateProgress(1, "could not load rdf data", true );
				//Ext.getCmp("progressBar").syncProgressBar();
				//Ext.getCmp("progressBar").updateText("waiting");
				//Ext.getCmp("progressBar").reset();
				//Ext.getCmp("progressBar").show();
        }
        setTimeout('',600);
    //Ext.getCmp("progressBar").syncProgressBar();
       
       //this.setName("test");
       
        var options = {};
        
        OpenLayers.Util.extend(options, this.formatOptions);
        
        if (this.map && !this.projection.equals(this.map.getProjectionObject())) {
            options.externalProjection = this.projection;
            options.internalProjection = this.map.getProjectionObject();
        }    
        
        var format = new OsmRdfFormat(options);
        var features = format.read(doc);
        
        for (var i = 0; i < features.length; i++) {
            var data = {};
            var feature = features[i];
            
            // we don't support features with no geometry in the GeoRSS
            // layer at this time. 
            if (!feature.geometry) {
                continue;
            } 
           /* if (feature.attributes.description.split("Same As: ")[1].split("</div>")[0] == "not yet entered") {
                continue;
            }   */
                       
            
            var title = feature.attributes.title ? 
                         feature.attributes.title : "Untitled";
            
            var description = feature.attributes.description ? 
                         feature.attributes.description : "No description.";
            
            var link = feature.attributes.uri;
	
			var nodeID = feature.attributes.nodeID;
	        googleProjection = new OpenLayers.Projection("EPSG:900913");

	        wgs84Projection = new OpenLayers.Projection("EPSG:4326");
            var location = feature.geometry.getBounds().getCenterLonLat().transform(wgs84Projection,googleProjection) ;
            feature.geometry=feature.geometry.transform(wgs84Projection,googleProjection) ;
            
            data.icon = this.icon == null ? 
                                     OpenLayers.Marker.defaultIcon() : 
                                     this.icon.clone();
            
            data.popupSize = this.popupSize ? 
                             this.popupSize.clone() :
                             new OpenLayers.Size(250, 120);
            var contentHTML;
            if (title || description) {
                // we have supplemental data, store them.
                data.title = title;
                data.description = description;
            
                contentHTML = '<div class="olLayerGeoRSSClose">[x]</div>'; 
                contentHTML += '<div class="olLayerGeoRSSTitle">';
                if (link) {
                    contentHTML += '<a class="link" href="'+link+'" target="_blank">'+nodeID+'</a>';
                }
                contentHTML += '</div>';
                contentHTML += '<div style="" class="olLayerGeoRSSDescription">';
                contentHTML += description;
                contentHTML += '</div>';
                data['popupContentHTML'] = contentHTML;                
            }
           // var feature = new OpenLayers.Feature(this, location, data);
           //var feature = new OpenLayers.Feature.Vector(feature.geometry);
           feature.data=data;
			feature.layer=this;
            feature.marker=new OpenLayers.Marker(new OpenLayers.LonLat(feature.geometry.x,feature.geometry.y),data.icon);
            feature.popup=popup = new OpenLayers.Popup(null,
                   new OpenLayers.LonLat(feature.geometry.x,feature.geometry.y),
                   data.popupSize,contentHTML
                   //,true
                   );

            this.features.push(feature);
          //  var marker = feature.createMarker();
            feature.marker.events.register('click', feature, this.markerClick);
            this.addMarker(feature.marker);
        }
        this.events.triggerEvent("loadend");
        	this.loaded=true;
        		//Ext.getCmp("progressBar").updateProgress(1, "finished", true );
        		//Ext.getCmp("progressBar").syncProgressBar();
				//Ext.getCmp("progressBar").updateText("waiting");
				//Ext.getCmp("progressBar").reset();
				//Ext.getCmp("progressBar").hide();
    },
    
    
    /**
     * Method: markerClick
     *
     * Parameters:
     * evt - {Event} 
     */
    markerClick: function(evt) {
   	// $(".container").show();
        var sameMarkerClicked = (this == this.layer.selectedFeature);
        this.layer.selectedFeature = (!sameMarkerClicked) ? this : null;
        for(var i=0; i < this.layer.map.popups.length; i++) {
            this.layer.map.removePopup(this.layer.map.popups[i]);
        }
        if (!sameMarkerClicked) {            
            var popup = this.popup;
            OpenLayers.Event.observe(popup.div, "click",
                OpenLayers.Function.bind(function() { 
                    for(var i=0; i < this.layer.map.popups.length; i++) { 
                        this.layer.map.removePopup(this.layer.map.popups[i]); 
                    }
                }, this)
            );
            this.layer.map.addPopup(popup);
            annoContent = popup.contentHTML;
	      //  dpLink = annoContent.split("Same As: ")[1].split("</div>")[0];
		    dpLink=this.layer.selectedFeature.attributes.sameAs;
		    
		    //show rdf in the right tab
		    if(dpLink!=null && dpLink.length>10){
		    	showRDF(Url.encode(dpLink)); 
		    }
		    
			currentSameAsNodeID=this.layer.selectedFeature.data.title.split(":")[1];
			


    	

        }             
        OpenLayers.Event.stop(evt);
    },

    /**
     * Method: clearFeatures
     * Destroy all features in this layer.
     */
    clearFeatures: function() {
        if (this.features != null) {
            while(this.features.length > 0) {
                var feature = this.features[0];
                OpenLayers.Util.removeItem(this.features, feature);
                feature.destroy();
            }
        }        
    },
    
    CLASS_NAME: "OsmRdfLayer"
});

